// 游戏画布设置
const COLLISION_TYPE = { NONE: 0, GAME_OVER: 1, SPRING_WALL_HIT: 2 };

const canvas = document.getElementById('game-canvas');
const ctx = canvas.getContext('2d');
const gridSize = 20; // 网格大小
const gridWidth = canvas.width / gridSize;
const gridHeight = canvas.height / gridSize;

// 游戏状态
let gameRunning = false;
let gamePaused = false;
let gameOver = false;
let score = 0;
let speed = 150; // 初始速度，毫秒
let speedLevel = 1; // 速度等级，1-10
let speedIncrement = 2; // 每吃一个食物增加的速度
let springMode = false; // 弹簧模式状态
let isReversing = false; // 标记蛇是否正在反向

// 速度相关常量
const MIN_SPEED = 50; // 最快速度（最小延迟）
const MAX_SPEED = 200; // 最慢速度（最大延迟）
const SPEED_STEP = 15; // 每次调整的速度步长

// 蛇的初始设置
let snake = [
    { x: Math.floor(gridWidth / 2), y: Math.floor(gridHeight / 2) }
];
let direction = 'right'; // 初始方向
let nextDirection = direction;

// 食物位置
let food = generateFood();

// 按钮元素
// 按钮元素
const startBtn = document.getElementById('start-btn');
const pauseBtn = document.getElementById('pause-btn');
const restartBtn = document.getElementById('restart-btn');
const scoreElement = document.getElementById('score');
const speedDisplay = document.getElementById('speed-display');
const increaseSpeedBtn = document.getElementById('increase-speed-btn');
const decreaseSpeedBtn = document.getElementById('decrease-speed-btn');
const springModeCheckbox = document.getElementById('spring-mode');

// 游戏循环
let gameInterval;

// 初始化游戏
// 初始化游戏
function initGame() {
    // 重置游戏状态
    gameRunning = false;
    gamePaused = false;
    gameOver = false;
    score = 0;
    speed = 150;
    speedLevel = 1;
    
    // 重置蛇
    snake = [
        { x: Math.floor(gridWidth / 2), y: Math.floor(gridHeight / 2) }
    ];
    direction = 'right';
    nextDirection = direction;
    
    // 生成新食物
    food = generateFood();
    
    // 更新分数和速度显示
    updateScore();
    updateSpeedDisplay();
    
    // 绘制初始状态
    draw();
    
    // 设置按钮状态
    startBtn.disabled = false;
    pauseBtn.disabled = true;
}

// 开始游戏
function startGame() {
    if (!gameRunning && !gameOver) {
        gameRunning = true;
        gamePaused = false;
        
        // 清除任何现有的游戏循环
        if (gameInterval) {
            clearInterval(gameInterval);
        }
        
        // 启动新的游戏循环
        gameInterval = setInterval(gameLoop, speed);
        
        startBtn.disabled = true;
        pauseBtn.disabled = false;
        pauseBtn.textContent = '暂停';
    }
}

// 暂停游戏
function togglePause() {
    if (gameRunning) {
        if (gamePaused) {
            // 恢复游戏
            gamePaused = false;
            gameInterval = setInterval(gameLoop, speed);
            pauseBtn.textContent = '暂停';
        } else {
             // 暂停游戏
            gamePaused = true;
            clearInterval(gameInterval);
            pauseBtn.textContent = '继续';
        }
    }
}

// 重新开始游戏
function restartGame() {
    clearInterval(gameInterval);
    initGame();
}

// 增加速度
function increaseSpeed() {
    if (speedLevel < 10) {
        speedLevel++;
        speed = calculateSpeedFromLevel(speedLevel);
        updateSpeedDisplay();
        
        // 如果游戏正在运行，更新游戏循环的速度
        if (gameRunning && !gamePaused) {
            clearInterval(gameInterval);
            gameInterval = setInterval(gameLoop, speed);
        }
    }
}

// 减少速度
function decreaseSpeed() {
    if (speedLevel > 1) {
        speedLevel--;
        speed = calculateSpeedFromLevel(speedLevel);
        updateSpeedDisplay();
        
        // 如果游戏正在运行，更新游戏循环的速度
        if (gameRunning && !gamePaused) {
            clearInterval(gameInterval);
            gameInterval = setInterval(gameLoop, speed);
        }
    }
}

// 根据速度等级计算实际速度（毫秒）
function calculateSpeedFromLevel(level) {
    // 将1-10的等级映射到MAX_SPEED-MIN_SPEED的范围
    // 等级越高，速度值越小（即移动越快）
    return MAX_SPEED - ((level - 1) * ((MAX_SPEED - MIN_SPEED) / 9));
}

// 更新速度显示
function updateSpeedDisplay() {
    speedDisplay.textContent = speedLevel;
}

// 游戏主循环
// 游戏主循环
function gameLoop() {
    if (!gamePaused && gameRunning) {
        // 更新蛇的方向
        direction = nextDirection;
        console.log('Game loop: direction set to', direction);
        
        // 移动蛇
        moveSnake();
        console.log('After moveSnake: snake =', JSON.stringify(snake));
        
        // 检查碰撞
        const collisionResult = checkCollision();
        console.log('Collision result:', collisionResult);
        switch (collisionResult) {
            case COLLISION_TYPE.GAME_OVER:
                endGame();
                return;
            case COLLISION_TYPE.SPRING_WALL_HIT:
                if (snake.length > 1) {
                    snake.shift();
                    console.log('After shift: snake =', JSON.stringify(snake));
                    
                    // Update direction for the new head
                    if (snake.length === 1) {
                        // For single-node, reverse direction
                        direction = {
                            'up': 'down',
                            'down': 'up',
                            'left': 'right',
                            'right': 'left'
                        }[direction];
                        nextDirection = direction;
                    } else if (snake.length > 1) {
                        reverseSnake();
                    }
                }
                break;
            case COLLISION_TYPE.NONE:
                // 没有碰撞，继续游戏
                break;
        }

        // 检查是否吃到食物
        if (snake[0].x === food.x && snake[0].y === food.y) {
            // 吃到食物，不移除尾部，蛇变长
            score += 10;
            updateScore();
            food = generateFood();
        } else if (collisionResult !== COLLISION_TYPE.SPRING_WALL_HIT) {
            // 没吃到食物且不是撞墙处理中，移除尾部以保持长度
            snake.pop();
            console.log('After pop: snake =', JSON.stringify(snake));
        }
        
        draw();
        isReversing = false;
    }
}

// 移动蛇
function moveSnake() {
    const head = { x: snake[0].x, y: snake[0].y };
    
    // 根据方向移动头部
    switch (direction) {
        case 'up':
            head.y -= 1;
            break;
        case 'down':
            head.y += 1;
            break;
        case 'left':
            head.x -= 1;
            break;
        case 'right':
            head.x += 1;
            break;
    }
    
    // 将新头部添加到蛇的身体数组的开头
    snake.unshift(head);
}

// 检查碰撞
// 检查碰撞
// 检查碰撞
function checkCollision() {
    const head = snake[0];
    
    // 检查是否撞墙
    if (head.x < 0 || head.x >= gridWidth || head.y < 0 || head.y >= gridHeight) {
        // 如果是弹簧模式，碰到墙壁时自动头尾互换而不是结束游戏
        if (springMode) {
            // 记录原始的碰撞方向
            let collisionDirection = '';
            if (head.x < 0) collisionDirection = 'left';
            else if (head.x >= gridWidth) collisionDirection = 'right';
            else if (head.y < 0) collisionDirection = 'up';
            else if (head.y >= gridHeight) collisionDirection = 'down';

            // 将头部调整回有效范围内
            if (head.x < 0) head.x = 0;
            if (head.x >= gridWidth) head.x = gridWidth - 1;
            if (head.y < 0) head.y = 0;
            if (head.y >= gridHeight) head.y = gridHeight - 1;

            // 如果蛇只有一个节点，直接改变方向为相反方向并移动一格
            console.log(`checkCollision: Snake length is ${snake.length}.`);
            if (snake.length === 1) {
                  // 直接反向
                direction = {
                    'up': 'down',
                    'down': 'up',
                    'left': 'right',
                    'right': 'left'
                }[collisionDirection];
                nextDirection = direction; // 确保 nextDirection 也更新，以便 gameLoop 使用正确方向
                snake[0] = head; // 更新蛇头到墙边位置
                return COLLISION_TYPE.SPRING_WALL_HIT; // 返回单节点弹簧模式碰撞类型
            } else {
                // 对于多节点，我们不在checkCollision中反转，而是交给gameLoop处理
                return COLLISION_TYPE.SPRING_WALL_HIT;
            }
        } else {
            return COLLISION_TYPE.GAME_OVER; // 非弹簧模式撞墙游戏结束
        }
    }

    // 检查是否撞到自己


    for (let i = 2; i < snake.length; i++) { // Keep i=2 as per the comment
        if (head.x === snake[i].x && head.y === snake[i].y) {

            return COLLISION_TYPE.GAME_OVER; // 撞到自己总是结束游戏，即使在弹簧模式下
        }
    }

    return COLLISION_TYPE.NONE; // 没有碰撞
}

// 生成食物
function generateFood() {
    let newFood;
    let foodOnSnake;
    const margin = 3; // 边缘安全距离，避免食物生成在最边缘的几格内
    
    // 确保食物不会生成在蛇身上和边缘区域
    do {
        foodOnSnake = false;
        // 生成食物时避开边缘区域
        newFood = {
            x: margin + Math.floor(Math.random() * (gridWidth - 2 * margin)),
            y: margin + Math.floor(Math.random() * (gridHeight - 2 * margin))
        };
        
        // 检查食物是否在蛇身上
        for (let segment of snake) {
            if (segment.x === newFood.x && segment.y === newFood.y) {
                foodOnSnake = true;
                break;
            }
        }
    } while (foodOnSnake);
    
    return newFood;
}

// 绘制游戏
// 绘制游戏
function draw() {
    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // 绘制蛇
    for (let i = 0; i < snake.length; i++) {
        // 蛇头用不同颜色
        if (i === 0) {
            ctx.fillStyle = '#1A237E'; // 深蓝色蛇头
        } else {
            ctx.fillStyle = '#303F9F'; // 蓝色蛇身
        }
        
        // 绘制蛇的身体部分
        ctx.fillRect(
            snake[i].x * gridSize,
            snake[i].y * gridSize,
            gridSize - 1,
            gridSize - 1
        );
        
        // 为蛇的身体添加边框，使其在草地背景上更加明显
        ctx.strokeStyle = '#C5CAE9';
        ctx.lineWidth = 1;
        ctx.strokeRect(
            snake[i].x * gridSize,
            snake[i].y * gridSize,
            gridSize - 1,
            gridSize - 1
        );
    }
    
    // 绘制食物（苹果）
    ctx.fillStyle = '#D32F2F'; // 红色苹果
    ctx.beginPath();
    ctx.arc(
        food.x * gridSize + gridSize/2,
        food.y * gridSize + gridSize/2,
        gridSize/2 - 1,
        0,
        Math.PI * 2
    );
    ctx.fill();
    
    // 添加苹果柄
    ctx.fillStyle = '#795548'; // 棕色
    ctx.fillRect(
        food.x * gridSize + gridSize/2 - 1,
        food.y * gridSize + 2,
        2,
        5
    );
    
    // 如果游戏结束，显示游戏结束文字
    if (gameOver) {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        ctx.font = '30px Arial';
        ctx.fillStyle = 'white';
        ctx.textAlign = 'center';
        ctx.fillText('游戏结束', canvas.width / 2, canvas.height / 2 - 15);
        
        ctx.font = '20px Arial';
        ctx.fillText(`最终得分: ${score}`, canvas.width / 2, canvas.height / 2 + 20);
    }
}

// 更新分数显示
function updateScore() {
    scoreElement.textContent = score;
}

// 游戏结束
function endGame() {
    gameRunning = false;
    gameOver = true;
    clearInterval(gameInterval);
    draw(); // 绘制游戏结束画面
    startBtn.disabled = true;
    pauseBtn.disabled = true;
}

// 键盘控制
// 键盘控制
document.addEventListener('keydown', (event) => {
    if (gameRunning && !gamePaused) {
        switch (event.key) {
            case 'ArrowUp':
            case 'w':
            case 'W':
                // 只有在弹簧模式下，或者蛇只有一个节点，或者新方向不是当前方向的相反方向时，才改变方向
                if (snake.length === 1 || direction !== 'down') nextDirection = 'up';
                break;
            case 'ArrowDown':
            case 's':
            case 'S':
                // 只有在弹簧模式下，或者蛇只有一个节点，或者新方向不是当前方向的相反方向时，才改变方向
                if (snake.length === 1 || direction !== 'up') nextDirection = 'down';
                break;
            case 'ArrowLeft':
            case 'a':
            case 'A':
                // 只有在弹簧模式下，或者蛇只有一个节点，或者新方向不是当前方向的相反方向时，才改变方向
                if (snake.length === 1 || direction !== 'right') nextDirection = 'left';
                break;
            case 'ArrowRight':
            case 'd':
            case 'D':
                // 只有在弹簧模式下，或者蛇只有一个节点，或者新方向不是当前方向的相反方向时，才改变方向
                if (snake.length === 1 || direction !== 'left') nextDirection = 'right';
                break;
            case 'Control': // Ctrl键
                reverseSnake(); // 头尾互换
                break;
        }
    }
});

// 蛇头尾互换函数
// 蛇头尾互换函数
function reverseSnake() {
    console.log('reverseSnake called. Snake before reverse:', JSON.stringify(snake));
    isReversing = true; // Set flag when reversal happens
    console.log('Current direction:', direction);
    // 如果蛇只有一个节点，则改变方向为相反方向
    if (snake.length === 1) {
        // 根据当前方向设置相反方向
        switch (direction) {
            case 'up':
                direction = 'down';
                nextDirection = 'down';
                break;
            case 'down':
                direction = 'up';
                nextDirection = 'up';
                break;
            case 'left':
                direction = 'right';
                nextDirection = 'right';
                break;
            case 'right':
                direction = 'left';
                nextDirection = 'left';
                break;
        }
    } else {
        // 多个节点时，反转整个蛇的身体
        snake.reverse();
        console.log('Snake after snake.reverse():', JSON.stringify(snake));
        // 根据新的头部（原来的尾部）位置，确定新的移动方向
        const head = snake[0];
        const neck = snake[1];
        console.log('Head:', JSON.stringify(head), 'Neck:', JSON.stringify(neck));

        // 根据头部和第二节的相对位置确定新方向
        if (head.x < neck.x) {
            direction = 'left';
        } else if (head.x > neck.x) {
            direction = 'right';
        } else if (head.y < neck.y) {
            direction = 'up';
        } else if (head.y > neck.y) {
            direction = 'down';
        }
        nextDirection = direction; // 确保 nextDirection 也更新
    }
    console.log('Snake after reverse:', JSON.stringify(snake));
    console.log('New direction:', direction, 'New nextDirection:', nextDirection);
    
    // 立即重绘游戏画面
    draw();
}

// 按钮事件监听
startBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', togglePause);
restartBtn.addEventListener('click', restartGame);
increaseSpeedBtn.addEventListener('click', increaseSpeed);
decreaseSpeedBtn.addEventListener('click', decreaseSpeed);
springModeCheckbox.addEventListener('change', function() {
    springMode = this.checked;
});

// 初始化游戏
initGame();